import asyncio
import collections
import sys
import threading

from tornado.ioloop import IOLoop

try:
  import message_queue
except ImportError:
  pass


class MessageQueue(object):
  def __init__(self, loop):
    self._num_msg = 0
    self._loop = loop
    self._lock = threading.Lock()
    self._filled_future = collections.deque()
    self._empty_future = collections.deque()
    message_queue.set_python_callback(self.on_message)

  def on_message(self, msg):
    with self._lock:
      self._num_msg += 1
      if len(self._empty_future) > 0:
        future = self._empty_future.popleft();
      else:
        future = self._loop.create_future()
        self._filled_future.append(future)
      print('message: ', msg)
      self._loop.call_soon_threadsafe(future.set_result, msg)

  def read_message(self):
    with self._lock:
      if len(self._filled_future) > 0:
        future = self._filled_future.popleft()
      else:
        future = self._loop.create_future()
        self._empty_future.append(future);
      return future


async def periodic_print():
  n = 0
  while True:
    print('current: %s' % n)
    n = n + 1
    await asyncio.sleep(1)


async def main(loop):
  #loop.add_callback(periodic_print())
  queue = MessageQueue(asyncio.get_running_loop())
  while True:
    message = await queue.read_message()
    print("receive message from cpp: " + message)
    message_queue.write_message("from py: " + message)


loop = tornado.ioloop.IOLoop.current()
asyncio.run(main(loop))
print("python done")
